window.dom = {
    create(string) {
        const container = document.createElement('template');
        // 使用template 可以容纳任何类型的标签，不会报错
        container.innerHTML = string.trim();
        return container.content.firstChild
        // 返回创建的标签
    },

    after(node, node2){
        node.parentNode.insertBefore(node2, node.nextSibling);
    },

    before(node, node2){
        node.parentNode.insertBefore(node2, node)
    },

    append(parent, node){
        parent.appendChild(node)
    },

    wrap(node, parent){
    // 将node 节点变为parent 节点的子节点
        dom.before(node, parent)
        // 将新节点parent 放在node 节点的前面
        dom.append(parent, node)
        // 将node 节点放在parent 节点里面（移动）
    },

    remove(node){
        node.parentNode.removeChild(node)
        return node
    },

    empty(node){
        // const {childNodes} = node
        // const childNodes = node.childNodes
        const array = []
        let item = node.firstChild
        while(item){
            array.push(dom.remove(node.firstChild))
            item = node.firstChild
        }
        return array
    },

    attr(node, name, value){    // 重载
        if(arguments.length === 3){
            node.setAttribute(name, value)
            // 若传入3个参数，写入标签属性值
        } else if(arguments.length === 2){
            return node.getAttribute(name)
            // 若传入2个参数，读取标签属性值并返回
        }
    },

    text(node, string){ // 适配ie，有innerText 字样，就用第一个方法
        if(arguments.length === 2){
            ('innerText' in node) ? (node.innerText = string) : (node.textContent = string)
        } else if(arguments.length === 1){
            return ('innerText' in node) ? (node.innerText) : (node.textContent)
        }
    },

    html(node, string){ // 重载
        if(arguments.length === 2){
            node.innerHTML = string
        } else if(arguments.length === 1){
            return node.innerHTML
        }
    },

    style(node, name, value){
        if(arguments.length === 3){
        // dom.style(div, 'color', 'red')
            node.style[name] = value
        }else if(typeof name === 'string'){
        // dom.style(div, 'color')
            return node.style[name]
        }else if(name instanceof Object){
        // dom.style(div, {color:'red'})
            const object = name
            for(let key in object){
                node.style[key] = object[key]
                // 这里不能使用node.style.key，会转换为字符串
            }
        }
        
    },

    class: {
        add(node, className){
            node.classList.add(className)
        },
        remove(node, className){
            node.classList.remove(className)
        },
        has(node, className){
            return node.classList.contains(className)
        }
    },

    on(node, eventName, fn){
        node.addEventListener(eventName,fn)
    },

    off(node, eventName,fn){
        node.removeEventListener(eventName, fn)
    },

    find(selector,scope){
        return (scope || document).querySelectorAll(selector)
        // 根据是否有scope，在 指定标签/全局 ，根据传入的选择器进行查找
        // 返回一个数组
    },

    parent(node){
        return node.parentNode
    },

    children(node){
        return node.children
    },

    siblings(node){
        return Array.from(node.parentNode.children).filter(n=>n!== node)
        // 找到父节点的所有子节点，并过滤掉自身
        // Array.from 将伪数组转为数组
    },

    next(node){
        let notText = node.nextSibling
        while(notText && notText.nodeType === 3){
            notText = notText.nextSibling
        }   // 如果是文本节点，就一直找到非文本节点
        return notText
    },

    previous(node){
        let notText = node.previousSibling
        while(notText && notText.nodeType === 3){
            notText = notText.previousSibling
        }   // 如果是文本节点，就一直找到非文本节点
        return notText
    },

    each(nodeList, fn){
        for(let i=0; i<nodeList.length; i++){
            fn.call(null, nodeList[i])
        }
    },

    index(node){
        const list = dom.children(node.parentNode)
        let i
        for(i=0; i<list.length; i++){
            if(list[i] === node){
                break
            }
        }
        return i
    },


}

